package com.ruoyi.oto.service.impl;

import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.MemberUser;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.oto.constants.*;
import com.ruoyi.oto.domain.*;
import com.ruoyi.oto.domain.dto.*;
import com.ruoyi.oto.domain.vo.DemandsDepartDetailVO;
import com.ruoyi.oto.domain.vo.DemandsDepartVO;
import com.ruoyi.oto.domain.vo.DemandsRecordDetailVO;
import com.ruoyi.oto.mapper.DemandsDepartMapper;
import com.ruoyi.oto.mapper.DemandsRecordMapper;
import com.ruoyi.oto.service.BranchLinkService;
import com.ruoyi.oto.service.CompanyCoreService;
import com.ruoyi.oto.service.DemandsDepartService;
import com.ruoyi.oto.service.DemandsRecordService;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 诉求记录服务
 *
 * @author ruoyi
 */
@Service
public class DemandsRecordServiceImpl extends ServiceImpl<DemandsRecordMapper, DemandsRecord> implements DemandsRecordService {
    @Autowired
    private CompanyCoreService companyCoreService;

    @Autowired
    private DemandsDepartService demandsDepartService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private DemandsDepartMapper demandsDepartMapper;

    @Autowired
    private BranchLinkService branchLinkService;


    /**
     * 保存诉求记录
     *
     * @param memberUser
     * @param demandsCompanyDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveDemandsRecord(MemberUser memberUser, DemandsCompanyDTO demandsCompanyDTO) {
        //查询当前用户管理的企业
        CompanyCore companyCore = companyCoreService.getCompanyByMemberId(memberUser.getId());
        if (ObjUtil.isNull(companyCore)) {
            throw new ServiceException("您还没有管理企业");
        }
        if(!DemandTypes.网上举报.equals(demandsCompanyDTO.getDemandsType()) || !demandsCompanyDTO.getAnonymous()){ //非纪检投诉 或者 是纪检投诉但是非匿名
            if(!ReUtil.isMatch(RegexPool.CHINESES,demandsCompanyDTO.getContact())){
                throw new ServiceException("请填写正确的联系人姓名（中文）");
            }
            if(!ReUtil.isMatch(RegexPool.MOBILE,demandsCompanyDTO.getContactPhone())){
                throw new ServiceException("请填写正确的联系电话");
            }
        }
        //生成一条诉求记录
        DemandsRecord.DemandsRecordBuilder builder = DemandsRecord.builder().demandsType(demandsCompanyDTO.getDemandsType()).title(demandsCompanyDTO.getTitle())
                .content(demandsCompanyDTO.getContent()).images((demandsCompanyDTO.getImages()!=null && !demandsCompanyDTO.getImages().isEmpty())?StrUtil.join(",",demandsCompanyDTO.getImages()):null)
                .anonymous(demandsCompanyDTO.getAnonymous())
                .contact(demandsCompanyDTO.getContact()).contactPhone(demandsCompanyDTO.getContactPhone())
                .sendType(0).companyId(companyCore.getId()).companyName(companyCore.getCompanyName())
                .status(DemandStatus.未审核).acceptStatus(DemandAcceptStatus.未受理)
                .isEnd(YesNoFlag.NO);
        /*if(!DemandTypes.网上举报.equals(demandsCompanyDTO.getDemandsType())){
            //如果是匿名诉求,直接到纪工委账号
            //找本企业的联企人员
            BranchLink branchLink = new BranchLink();
            branchLink = branchLink.selectOne(new LambdaQueryWrapper<BranchLink>().eq(BranchLink::getCompanyId, companyCore.getId()).eq(BranchLink::getDelFlag,DeleteFlag.NO));
            if (branchLink != null) {
                builder.memberId(branchLink.getMemberId());
                builder.memberName(branchLink.getMemberName());
            }
        }*/
        DemandsRecord demandsRecord = builder.build();
        boolean result = demandsRecord.insert();
        if(DemandTypes.网上举报.equals(demandsCompanyDTO.getDemandsType())){
            //分发的纪检部门
            SysDept jwSysDept = sysDeptService.getJwSysDept();
            Long jwDeptId = ObjUtil.isNotNull(jwSysDept)?jwSysDept.getDeptId():-1L;
            demandsDepartService.addDemandsDepartToJw(demandsRecord,jwDeptId,0L);
        }
        return result;
    }

    /**
     * 审核诉求
     *
     * @param loginUser  当前的登陆账号
     * @param checkDemandsDTO 审核内容
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long checkDemands(LoginUser loginUser, CheckDemandsDTO checkDemandsDTO) {
        DemandsRecord demandsRecord = new DemandsRecord();
        demandsRecord = demandsRecord.selectById(checkDemandsDTO.getDemandsId());
        if (ObjUtil.isNull(demandsRecord)) {
            throw new ServiceException("未找到诉求记录");
        }
        if (checkDemandsDTO.getOp() == YesNoFlag.YES) {
            demandsRecord.setStatus(DemandStatus.处理中);
        } else {
            demandsRecord.setStatus(DemandStatus.审核不通过);
            if(StrUtil.isEmpty(checkDemandsDTO.getRemark())){
                throw new ServiceException("审核不通过要填写不通过原因");
            }
            demandsRecord.setRemark(checkDemandsDTO.getRemark());
        }
        if(loginUser.getMember()!=null){  //联企人员审核
            demandsRecord.setMemberId(loginUser.getMember().getId());
            demandsRecord.setMemberName(loginUser.getMember().getUsername());
            demandsRecord.setMemberCheckTime(new Date());
            demandsRecord.setUpdateBy(loginUser.getMember().getUsername());
            demandsRecord.setCheckMessage(checkDemandsDTO.getRemark());
        }
        else{  //职能部门人员审核
            BranchMember branchMember = new BranchMember();
            branchMember = branchMember.selectById(checkDemandsDTO.getMemberId());
            if(branchMember!=null){
                demandsRecord.setMemberId(branchMember.getId());
                demandsRecord.setMemberName(branchMember.getMemberName());
                demandsRecord.setMemberCheckTime(new Date());
            }
            demandsRecord.setUpdateBy(loginUser.getUser().getUserName());
            demandsRecord.setCheckMessage(checkDemandsDTO.getRemark());
        }
        demandsRecord.updateById();
        if (checkDemandsDTO.getOp() == YesNoFlag.YES) {
            if(checkDemandsDTO.getDeparts()==null && checkDemandsDTO.getDeparts().size()==0){
                throw new ServiceException("派发的部门不能为空");
            }
            for (int i = 0; i < checkDemandsDTO.getDeparts().size(); i++) {
                demandsDepartService.addDemandsDepart(loginUser, demandsRecord, checkDemandsDTO.getDeparts().get(i), 0L);
            }
        }
        // TODO 发送消息给 对应的企业
        return demandsRecord.getId();
    }

    /**
     * 分页查询诉求列表
     * @param memberUser
     * @param demandsQuryDTO
     * @return
     */
    @Override
    public IPage<DemandsRecord> listDemandsFront(MemberUser memberUser, DemandsQuryDTO demandsQuryDTO) {
        IPage<DemandsRecord> page = new Page<>(demandsQuryDTO.getCurrent(),demandsQuryDTO.getSize());
        Long companyId = -1L;
        List<Long> mymanagerCompanyIds = null;
        if(memberUser.getRoleId().equals(MemberRoleConstant.游客)){
            return new Page<>();
        }
        else if(memberUser.getRoleId().equals(MemberRoleConstant.企业用户)){
            //获取企业用户管理的企业
            CompanyCore companyCore = companyCoreService.getCompanyByMemberId(memberUser.getId());
            if(ObjUtil.isNull(companyCore)){
                throw new ServiceException("您还没有管理企业");
            }
            companyId = companyCore.getId();
            return this.page(page,new LambdaQueryWrapper<DemandsRecord>().eq(demandsQuryDTO.getStatus()!=null,DemandsRecord::getStatus,demandsQuryDTO.getStatus())
                    .eq(DemandsRecord::getCompanyId,companyId).orderByDesc(DemandsRecord::getCreateTime));
        }
        else if(memberUser.getRoleId().equals(MemberRoleConstant.联企用户)){
            //获取此联企用户管理的所有企业
            mymanagerCompanyIds = branchLinkService.getCompanyIdsByMemberId(memberUser.getId());
            return this.page(page,new LambdaQueryWrapper<DemandsRecord>().eq(demandsQuryDTO.getStatus()!=null,DemandsRecord::getStatus,demandsQuryDTO.getStatus())
                    .in(DemandsRecord::getCompanyId,mymanagerCompanyIds)
                    .orderByDesc(DemandsRecord::getCreateTime));
        }
        //这里隐含着领导账号可以查看所有的
        return this.page(page,new LambdaQueryWrapper<DemandsRecord>().eq(demandsQuryDTO.getStatus()!=null,DemandsRecord::getStatus,demandsQuryDTO.getStatus()));
    }

    /**
     * 小程序查看诉求详情
     * @param demandsId
     * @return
     */
    @Override
    public DemandsRecordDetailVO demandsDetail(LoginUser loginUser,Long demandsId) {
        DemandsRecordDetailVO demandsRecordDetailVO = new DemandsRecordDetailVO();
        DemandsRecord demandsRecord = this.getById(demandsId);
        if(ObjUtil.isNull(demandsRecord)) {
            throw new ServiceException("找不到此诉求");
        }
        //查找此诉求对应的企业
        CompanyCore companyCore = companyCoreService.getById(demandsRecord.getCompanyId());
        if(ObjUtil.isNull(companyCore)){
            throw new ServiceException("诉求对应的企业不存在");
        }
        if(loginUser.getMember().getRoleId().equals(MemberRoleConstant.企业用户) && !loginUser.getMember().getId().equals(companyCore.getMemberId())){
            throw new ServiceException("非法访问");
        }
        if(loginUser.getMember().getRoleId().equals(MemberRoleConstant.联企用户) && !branchLinkService.getCompanyIdsByMemberId(loginUser.getMember().getId()).contains(companyCore.getId())){
            throw new ServiceException("非法访问");
        }
        demandsRecordDetailVO.setDemandsRecord(demandsRecord);
        demandsRecordDetailVO.setCompanyCore(companyCore);
        //查找这个诉求参与的部门
        List<DemandsDepart> demandsDepartList = demandsDepartService.getDemandsDepartList(demandsId);
        List<DemandsRecordDetailVO.DemandsDepartAndReply> demandsDepartAndReplys = new ArrayList<>();
        demandsDepartList.forEach(demandsDepart -> {
            //获取每个部门的处置回复
            List<DemandsReply> demandsReplies = demandsDepartService.getDemandsReplyByDemandDepartId(demandsId, demandsDepart.getId());
            demandsDepartAndReplys.add(new DemandsRecordDetailVO.DemandsDepartAndReply(demandsDepart,demandsReplies));

        });
        demandsRecordDetailVO.setDemandsDepartAndReplys(demandsDepartAndReplys);
        return demandsRecordDetailVO;
    }

    /**
     * 获取部门要审核的诉求
     * @param deptId
     * @param demandsQuryDTO
     * @return
     */
    @Override
    public IPage<DemandsRecord> listCheckDemands(Long deptId, DemandsQuryDTO demandsQuryDTO) {
        IPage<DemandsRecord> page = new Page<>(demandsQuryDTO.getCurrent(),demandsQuryDTO.getSize());
        //获取纪工委的部门
        SysDept jwSysDept = sysDeptService.getJwSysDept();
        Long jwDeptId = ObjUtil.isNotNull(jwSysDept)?jwSysDept.getDeptId():-1L;
        return this.getBaseMapper().listCheckDemands(page,deptId,jwDeptId,demandsQuryDTO);
    }

    /**
     * 后台-分页查询要处理的诉求列表
     * @param loginUser
     * @param demandsQuryDTO
     * @return
     */
    @Override
    public IPage<DemandsRecord> listDemandsBack(LoginUser loginUser, DemandsQuryDTO demandsQuryDTO) {
        List<String> roleKeys = loginUser.getUser().getRoles().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
        if(roleKeys.contains(SysUserRoleCode.ADMIN)||roleKeys.contains(SysUserRoleCode.领导部门)||roleKeys.contains(SysUserRoleCode.营商中心)){
            //就可以查看
            IPage<DemandsRecord> page = new Page<>(demandsQuryDTO.getCurrent(),demandsQuryDTO.getSize());
            //这里隐含着领导账号可以查看所有的
            return this.page(page,new LambdaQueryWrapper<DemandsRecord>().eq(demandsQuryDTO.getStatus()!=null,DemandsRecord::getStatus,demandsQuryDTO.getStatus())
                    .ne(DemandsRecord::getDemandsType,DemandTypes.网上举报)
                    .orderByDesc(DemandsRecord::getCreateTime));
        }
        return new Page<>();
    }

    @Override
    public List<DemandsDepartVO> listDemandsDepartById(LoginUser loginUser, Long departId) {
        List<String> roleKeys = loginUser.getUser().getRoles().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
        if(roleKeys.contains(SysUserRoleCode.ADMIN)||roleKeys.contains(SysUserRoleCode.领导部门)||roleKeys.contains(SysUserRoleCode.营商中心)){
            return demandsDepartMapper.listDemandsDepartById(departId);
        }
        return new ArrayList<>();
    }

    /**
     * 获取我的部门待处理的诉求
     * @param loginUser
     * @param demandsQuryDTO
     * @return
     */
    @Override
    public IPage<DemandsDepartVO> listDemandsDepart(LoginUser loginUser, DemandsQuryDTO demandsQuryDTO) {
        List<String> roleKeys = loginUser.getUser().getRoles().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
        Long branchId = loginUser.getDeptId();
        if(roleKeys.contains(SysUserRoleCode.ADMIN) ||roleKeys.contains(SysUserRoleCode.领导部门) ||roleKeys.contains(SysUserRoleCode.营商中心) ){
            branchId = null;
        }
        IPage<DemandsDepartVO> page = new Page<>(demandsQuryDTO.getCurrent(),demandsQuryDTO.getSize());
        //这里隐含着领导账号可以查看所有的
        return demandsDepartMapper.listDemandsDepart(page,branchId,demandsQuryDTO);
    }

    /**
     * 获取受理详情
     * @param acceptId
     * @return
     */
    @Override
    public DemandsDepartDetailVO listDemandsDepartReply(Long acceptId) {
        DemandsDepart demandDepart = demandsDepartService.getById(acceptId);
        DemandsRecord demandsRecord = this.getById(demandDepart.getDemandsId());
        CompanyCore companyCore = companyCoreService.getById(demandsRecord.getCompanyId());
        DemandsReply demandsReply = new DemandsReply();
        List<DemandsReply> demandsReplies = demandsReply.selectList(
                new LambdaQueryWrapper<DemandsReply>().eq(DemandsReply::getDemandsDepartId, demandDepart.getId())
                        .orderByDesc(DemandsReply::getCreateTime)
        );
        return new DemandsDepartDetailVO(companyCore,demandsRecord,demandDepart,demandsReplies);
    }

    /**
     * 后台经办答复诉求
     * @param loginUser
     * @param replyDemandsDTO
     * @return
     */
    @Override
    public DemandsReply replyDemandsBack(LoginUser loginUser, ReplyDemandsDTO replyDemandsDTO) {
        DemandsDepart demandsDepart = demandsDepartMapper.selectById(replyDemandsDTO.getAcceptId());
        if(!loginUser.getDeptId().equals(demandsDepart.getBranchId())){
            throw new ServiceException("此诉求没有分配到你的部门");
        }
        if(demandsDepart.getStatus()==DemandsDepartStatus.驳回_转部门 || demandsDepart.getStatus()==DemandsDepartStatus.完成){
            throw new ServiceException("当前诉求已经结束,无法再回复");
        }
        if(replyDemandsDTO.getStatus()==DemandsDepartStatus.受理_处置){
            demandsDepart.setStatus(DemandsDepartStatus.受理_处置);
            if(ObjUtil.isNull(replyDemandsDTO.getChargeTime())){
                throw new ServiceException("预计完成时间不能为空");
            }
            if(ObjUtil.isNull(replyDemandsDTO.getAcceptContent())){
                throw new ServiceException("受理内容不能为空");
            }
            demandsDepart.setAcceptContent(replyDemandsDTO.getAcceptContent());
            demandsDepart.setAcceptTime(new Date());
            demandsDepart.setUpdateTime(new Date());
            demandsDepart.updateById();
        }
        else if(replyDemandsDTO.getStatus()==DemandsDepartStatus.驳回_转部门){
            demandsDepart.setStatus(DemandsDepartStatus.驳回_转部门);
            demandsDepart.setAcceptContent(replyDemandsDTO.getAcceptContent());
            demandsDepart.setToBranchId(replyDemandsDTO.getToBranchId());
            if(replyDemandsDTO.getToBranchId()!=null){
                SysDept sysDept = sysDeptService.selectDeptById(replyDemandsDTO.getToBranchId());
                demandsDepart.setToBranchName(sysDept.getDeptName());
            }
            demandsDepart.setYsStatus(YsOpinion.受理中);
            demandsDepart.setAcceptTime(new Date());
            demandsDepart.setUpdateTime(new Date());
            demandsDepart.updateById();
        }
        else if(replyDemandsDTO.getStatus()==DemandsDepartStatus.呈报领导){
           if(demandsDepart.getStatus()!=DemandsDepartStatus.受理_处置){
               throw new ServiceException("呈报领导需要先受理");
           }
            //TODO 这里要做个消息发送
        }
        else if (replyDemandsDTO.getStatus()==DemandsDepartStatus.完成){
            demandsDepart.setStatus(DemandsDepartStatus.完成);
            demandsDepart.setAcceptContent(replyDemandsDTO.getAcceptContent());
            demandsDepart.setAcceptTime(new Date());
            demandsDepart.setUpdateTime(new Date());
            demandsDepart.updateById();
        }
        //创建答复记录
        DemandsReply.DemandsReplyBuilder builder = DemandsReply.builder();
        builder.demandsId(demandsDepart.getDemandsId()).demandsDepartId(demandsDepart.getId())
                        .chargeName(replyDemandsDTO.getChargeName()).chargePhone(replyDemandsDTO.getChargePhone())
                        .chargeTime(replyDemandsDTO.getChargeTime()).acceptContent(replyDemandsDTO.getAcceptContent())
                        .status(replyDemandsDTO.getStatus());
        DemandsReply demandsReply = builder.build();
        demandsReply.setCreateBy(loginUser.getUsername());
        demandsReply.setCreateTime(new Date());
        demandsReply.insert();
        return demandsReply;
    }

    /**
     * 后台营商中心介入审核
     * @param loginUser
     * @param ysReplyDemandsDTO
     * @return
     */
    @Override
    public DemandsReply ysReplyDemandsBack(LoginUser loginUser, YsReplyDemandsDTO ysReplyDemandsDTO) {
        DemandsDepart demandsDepart = demandsDepartMapper.selectOne(new LambdaQueryWrapper<DemandsDepart>().eq(DemandsDepart::getId,ysReplyDemandsDTO.getAcceptId()).eq(DemandsDepart::getYsStatus,YsOpinion.受理中));
        if(demandsDepart==null){
            throw new ServiceException("此诉求不处于营商中心介入状态");
        }
        if(ysReplyDemandsDTO.getStatus()==YesNoFlag.YES){  //如果同意
            List<Long> moreBranchIds = ysReplyDemandsDTO.getMoreBranchIds();
            if(ObjUtil.isNull(moreBranchIds)||ObjUtil.isEmpty(moreBranchIds)){
                throw new ServiceException("请选择要转入的部门");
            }
            demandsDepart.setYsStatus(YsOpinion.同意);
            for(Long moreBranchId : moreBranchIds){
                //将此诉求转到其他的部门
                DemandsRecord demandsRecord = this.getById(demandsDepart.getDemandsId());
                demandsDepartService.addDemandsDepart(loginUser, demandsRecord, moreBranchId, demandsDepart.getBranchId());
            }
        }
        else{
            demandsDepart.setYsStatus(YsOpinion.驳回);
            demandsDepart.setStatus(DemandsDepartStatus.受理_处置);
            demandsDepart.setToBranchId(null);
            demandsDepart.setToBranchName(null);
        }
        demandsDepart.updateById();
        //创建答复记录
        DemandsReply.DemandsReplyBuilder builder = DemandsReply.builder();
        builder.demandsId(demandsDepart.getDemandsId()).demandsDepartId(demandsDepart.getId())
                .chargeName(ysReplyDemandsDTO.getChargeName()).chargePhone(ysReplyDemandsDTO.getChargePhone())
                .acceptContent(ysReplyDemandsDTO.getAcceptContent())
                .status(ysReplyDemandsDTO.getStatus());
        DemandsReply demandsReply = builder.build();
        demandsReply.setCreateBy(loginUser.getUsername());
        demandsReply.setCreateTime(new Date());
        demandsReply.insert();
        return demandsReply;
    }
}
